<template>


  <div class="gis_content" >

      <div class="gis_loading" v-if="!isLoadingForModel">
         
          <span>模型加载中{{loadPercent}}</span>

    </div>

    <div class="gis_content" ref="gis">

    </div>

  

      <vx-popup title="添加测点" width="450px" @close="cancelTreeSubmit" :active.sync="isAddPoint"
          @confirmPopup="submit" @cancelPopup="cancelTreeSubmit">
             
          <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
            <el-form-item label="一级分类" prop="firstType" >
              <el-select v-model="ruleForm.firstType" placeholder="请选择截面" @change="changeFirstType">
                <el-option v-for="(item, index) in showAllTypeList" :key="index" :label="item.name" :value="item.id" ></el-option>
              </el-select>
            </el-form-item>
        </el-form>

           <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm" >
              <el-form-item label="二级分类" prop="secondType" >
                <el-select v-model="ruleForm.secondType" placeholder="请选择截面" @change="changeSecondType">
                  <el-option v-for="(item, index) in showSecTypeList" :key="index" :label="item.name" :value="item.id" ></el-option>
                </el-select>
              </el-form-item>
            </el-form>

            <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
                <el-form-item label="选择测点" prop="thirdType" >
                  <el-select v-model="ruleForm.thirdType" placeholder="请选择截面" @change="changeThirdType">
                    <el-option v-for="(item, index) in showThirdList " :key="index" :label="item.name" :value="item.id" ></el-option>
                  </el-select>
            </el-form-item>
        </el-form>

    </vx-popup>



        
  </div>

  
</template>
<script>

import base from "@/api/base";
import { getDataForBridgeModel,openDb, updateBridModel } from '@/indexDb';

import * as Three from 'Three';
import { MTLLoader} from "three/examples/jsm/loaders/MTLLoader.js"
import { OBJLoader2} from "three/examples/jsm/loaders/OBJLoader2.js"
import { MtlObjBridge } from "three/examples/jsm/loaders/obj2/bridge/MtlObjBridge.js";

export default {
  name: "bridgeBim",
  props: {
    bridgeId: {
      type: String
    }
  },
  data() {
    return {

      file: {
        obj: '',
        mtl: ''
      },
      isAddPoint: false,
      object3Dlayer: '',
      showAllTypeList: [],
      showSecTypeList: [],
      showThirdList: [],
      ruleForm: {
        firstType: '',
        secondType: '',
        thirdType: ''
      },
      singleThirdInfo: {},
      lnglat: {
        xaxis: 0,
        yaxis: 0
      },
       rules:{},
       markPointList: [],
       markForMapList: [],
       loadPercent: 0,
       isLoadingForModel: false
     
    }
  },

  created() {
       openDb();
  },
  mounted() {

    this.queryBridgeBasicById();

 
 
  
    
  },
  destroyed(){

         this.object3Dlayer && this.object3Dlayer.clear()
        this.map.clearMap();
        this.map = null;
     
  },

  methods: {
     async queryBridgeBasicById() {

          let params = {
              appKey: 'FB',
              bridgeId: this.bridgeId
          }

          const result =  await this.$api.bridge.queryBridgeBasicById(params);

          if(result.data.success) {

            let data = result.data.data;

            this.queryModelfile(data[0][0].bimFolderId);

          }
      },

      async queryModelfile (id) {

        const resultDb = await getDataForBridgeModel(this.bridgeId);
        
        if (resultDb) {

           this.file = resultDb
           this.initMap();
          return;
        }
        let params = {

            folderId: id
        }

        const result  = await this.$api.bridge.getModelFolder(params);

        if (result.data.success) {

          let data = result.data.data;
          this.file = await this.getObjAndMtlFile(data)
         
            this.initMap();
                  updateBridModel(this.bridgeId, 'obj', this.file.obj, true) 
                  updateBridModel(this.bridgeId, 'mtl', this.file.mtl, true) 
        }
    
      },

      getObjAndMtlFile(data) {
 
          
          let file ={
            obj: '',
            mtl: ''
          }

          for(let i = 0; i< data.length; i++) {
             let item = data[i];

             if (item.fileSuffix === 'obj' && !file.obj){

               file.obj = base.DOWNLOADURL + item.filePath

             
             }
             if (item.fileSuffix === 'mtl' && !file.mtl){
                 file.mtl = base.DOWNLOADURL + item.filePath;
                
             }
             
             continue;
          };

          return file;
          
    
      },


      
      initMap ()  {
        
            const container = this.$refs.gis   
            this.map = new AMap.Map(container,{
                resizeEnable: true,
                zoom: 17,
                pitch: 45,
                rotation: 0,
                showIndoorMap: false,
                skyColor: 'red',
                viewMode:'3D',//开启3D视图,默认为关闭
                // mapStyle: 'amap://styles/0c0f079811878852272a7c19b9ed5c25',
            
                zooms:[3,24],
                center:[0, 0]
            });
            this.map.AmbientLight = new AMap.Lights.AmbientLight([1,1,1],1);
            this.map.DirectionLight = new AMap.Lights.DirectionLight([1,0,-0.5],[1,1,1],1);

            this.map.on('complete', () => {
                 
                 this.LoadObjModel()
                 this.queryAllFirstSystemDataType();
                 this.queryAllPointByBridgeId();
            
                 this.map.on('click', this.handleForMapClick)
            })
   
      },

      LoadObjModel ()  {

              
              const objLoader = new OBJLoader2();
              const _this = this;
              const callbackOnLoad = (event) => {
                  
                        

                          const object3Dlayer = _this.dealResult(event);

                       
                        
                          this.map.add(object3Dlayer);

                          
                }

                const onProgress = (xhr) => {
                  
                      let percent =  parseInt(xhr.loaded/xhr.total*100 + '');

                   
                      this.loadPercent = percent + '%'

                          
                      if (percent === 100) {

                        this.isLoadingForModel = true
                     
                      } 


                }
                
                  var onLoadMtl = function ( materials ) {
                      objLoader.addMaterials( MtlObjBridge.addMaterialsFromMtlLoader( materials ), true );
                      objLoader.load( _this.file.obj, callbackOnLoad, onProgress, ()=>{}, ()=>{} );
                  }
                  let mtlLoader = new MTLLoader();
                  mtlLoader.load( _this.file.mtl, onLoadMtl );
      },

      dealResult (event) {
            this.object3Dlayer = new AMap.Object3DLayer();
                    
            var meshes = event.children;

        
            for(var i=0;i<meshes.length;i++){
                var vecticesF3 = meshes[i].geometry.attributes.position;
                var vecticesNormal3 = meshes[i].geometry.attributes.normal;
                var vecticesUV2 = meshes[i].geometry.attributes.uv;

                var vectexCount =  vecticesF3.count;

                const mesh = new AMap.Object3D.MeshAcceptLights();

                var geometry = mesh.geometry;


                var c,opacity;

                var material = meshes[i].material[0]||meshes[i].material;
                

                c = material.color;
                opacity = material.opacity

                
                for(var j=0;j<vectexCount;j+=1){
                    var s = j*3;
                    geometry.vertices.push(vecticesF3.array[s],vecticesF3.array[s+2],-vecticesF3.array[s+1]);

                    if(vecticesNormal3) {
                        geometry.vertexNormals.push(vecticesNormal3.array[s],vecticesNormal3.array[s+2],-vecticesNormal3.array[s+1]);
                    }
                    if(vecticesUV2) {
                        geometry.vertexUVs.push(vecticesUV2.array[j*2],1-vecticesUV2.array[j*2+1]);
                    }
                    geometry.vertexColors.push(c.r,c.g,c.b,opacity)
                }

                mesh.DEPTH_TEST = material.depthTest
                mesh.transparent = opacity<1;
                mesh.scale(15, 15, 15)
                mesh.rotateZ(0)
                mesh.position(new AMap.LngLat(0, 0))
            
                
                this.object3Dlayer.add(mesh);
            }

            return this.object3Dlayer
       },
      
      handleForMapClick(event) {

        this.lnglat = {
           xaxis:  event.lnglat.lng,
           yaxis:  event.lnglat.lat
        }
         this.isAddPoint= true
      },

      cancelTreeSubmit() {
        this.isAddPoint= false

      },


     async queryAllFirstSystemDataType() {
          
           
          const result = await this.$api.bridge.queryAllFirstSystemDataType();

          if (result.data.success) {

             this.showAllTypeList = result.data.data[0]

          }
      },

      async changeFirstType(parentId){

        let params = {
          parentId: parentId
        }

        const result = await this.$api.bridge.queryAllSystemDataTypeByParentId(params);

        this.singleThirdInfo = {};

        if (result.data.success) {

           this.showSecTypeList = result.data.data[0];
           this.ruleForm = {
              firstType: this.ruleForm.firstType,
              secondType: '',
              thirdType: '',
           }
        }
 
         

      },

      async changeSecondType(id) {


          if (!this.ruleForm.firstType) {

              this.$vs.notify({
                text: "请选择一级分类",
                color: "warning"
              })

              return
          }
        
        
        let params = {
          ownId: this.bridgeId,
          measurePointSecondTypeId: id
        }
        this.singleThirdInfo = {};

        const result = await this.$api.bridge.queryAllDeviceMeasurePointBySecondTypeId(params);

        if (result.data.success) {

           this.ruleForm = {
              firstType: this.ruleForm.firstType,
              secondType: this.ruleForm.secondType,
              thirdType: '',
           }
           this.showThirdList = result.data.data[0]

      
        }

      },

      changeThirdType(id) {

          if (!this.ruleForm.secondType) {

              this.$vs.notify({
                text: "请选择二级分类",
                color: "warning"
              })

              return
          }

          let index = this.showThirdList.findIndex(item => item.id === id)

          this.singleThirdInfo = this.showThirdList[index];

      },

     async submit() {
         let info = this.singleThirdInfo

         if (!this.ruleForm.thirdType) {
            this.$vs.notify({
              text: "请选择测点",
              color: "warning"
            })
            return;
          }
          
         let params = {
           ...info,
           ...this.lnglat
          
         }

         delete params.createTime;

         delete params.updateTime;

         params.xaxis = params.xaxis + '';

         params.yaxis = params.yaxis + '';
         

        const result = await this.$api.bridge.batchUpdateDeviceMeasurePoint([params])

        if (result.data.success) {

            this.$vs.notify({
                text: "保存成功",
                color: "success"
              })
           this.isAddPoint = false;
           this.queryAllPointByBridgeId();
           
        }
         
      

      },


      async queryAllPointByBridgeId() {
        
         let params = {
            ownId: this.bridgeId
        }

       const result = await this.$api.bridge.queryAllPointByBridgeId(params);

       if (result.data.success) {

         this.markPointList = result.data.data[0];

         this.addMarksForMap(result.data.data[0])

       }

      },

       addMarksForMap (list) {
            

           if (list.length === 0) {
                   return;
           }
   
             const _this = this;

             if (this.markForMapList.length > 0) {
                  this.map.remove(this.markForMapList);
             
               
             }

          
            for (let i = 0; i< list.length; i++) {
            
                let item = list[i];
             
               if (this.isValidateValue(item.xaxis) && this.isValidateValue(item.yaxis) ){
                    continue
               }
                 

                const marker = new AMap.Marker({
                 
                    position: [item.xaxis || 0.005, item.yaxis || 0.001],
                    offset: new AMap.Pixel(-13, -30)
                });
                marker.setMap(_this.map);

                this.markForMapList.push(marker);

                AMap.event.addListener(marker, 'click', () => {
                        
                    _this.handleMakerPointsForClick(item);
                })

            }


   },

   isValidateValue (value) {
      
     if (!value && value !== 0) {

        return true
     }
     return false

   },


   handleMakerPointsForClick(item) {

    
    const h = this.$createElement;
     this.$msgbox({
        title: '消息',
          message: h('p', null, [h('span', null, '是否删除')]),
          showCancelButton: true,
          confirmButtonText: '确定',
          cancelButtonText: '取消',
     }).then(action => {
         if (action === 'confirm') {

             this.deletePoint(item)

         }
     });
      

     

   },

   async deletePoint (item) {


 
        delete item.createTime;

        delete item.updateTime;
               
        item.xaxis = '';

        item.yaxis =  '';      
       
        const result = await this.$api.bridge.batchUpdateDeviceMeasurePoint([item])
       if (result.data.success) {
            this.$vs.notify({
                text: "删除成功",
                color: "success"
              })
            this.queryAllPointByBridgeId();
       }
   }


   


  },



  

 



 

 
};
</script>
<style lang="scss">
   .gis_content{
     width: 100%;
     height: 75vh;
     position: relative;
   }
   .gis_loading{
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 22;
    text-align: center;
    top: -5%;
    &>span{
        display: block;
        width: 100%;
        height: 40px;
        color: #000;
        position: absolute;
        top: 50%;
        margin-top: -40px;
    }
}

</style>